package io.github.wppli.domain.authenticate.service.engine.impl;

import io.github.wppli.domain.authenticate.model.entity.UserEntity;
import io.github.wppli.domain.authenticate.model.entity.SingInEntity;
import io.github.wppli.domain.authenticate.service.engine.IEngine;
import io.github.wppli.types.exception.UsernameOrPasswordNotCorrectException;
import io.github.wppli.types.security.constants.SecurityConstant;
import io.github.wppli.types.security.model.SecurityUser;
import io.github.wppli.types.security.util.CacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.TimeUnit;


/**
 * 使用密码方式登录
 * @author li--jiaqiang 2024−12−23
 */
@Service("passwordEngine")
public class PasswordEngine implements IEngine {

    private static final Logger log = LoggerFactory.getLogger(PasswordEngine.class);
    private final PasswordEncoder passwordEncoder;
    private final UserDetailsService userDetailsService;
    private final CacheService cacheService;
    public PasswordEngine(PasswordEncoder passwordEncoder, UserDetailsService userDetailsService, CacheService cacheService) {
        this.passwordEncoder = passwordEncoder;
        this.userDetailsService = userDetailsService;
        this.cacheService = cacheService;
    }

    @Override
    public void loginEngine(SingInEntity singInEntity, UserEntity userEntity) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 判断用户信息是否为空
        if (null == userEntity) {
            throw new UsernameOrPasswordNotCorrectException("Username or password not correct.");
        }
        // 判断是否设置密码
        if (null == userEntity.getPassword() || userEntity.getPassword().isEmpty()) {
            throw new UsernameOrPasswordNotCorrectException("Password not set.");
        }

        // 校验密码是否正确
        boolean matches = passwordEncoder.matches(singInEntity.getPasswordCode(), userEntity.getPassword());
        if (!matches) {
            throw new UsernameOrPasswordNotCorrectException("Password is incorrect.");
        }

        // 手动调用 userDetailsService() 方法
        SecurityUser securityUser = (SecurityUser) userDetailsService.loadUserByUsername(singInEntity.getContactInformation());
        // 缓存用户信息
        cacheService.setAuthorizationWithUsername(securityUser.getUsername(), securityUser, SecurityConstant.TOKEN_EXPIRE, TimeUnit.SECONDS);
        log.info("用户:{} 密码登录执行 loadUserByUsername() 方法完成 - Cache SecurityUser",securityUser.getUsername());
    }
}